package com.bckj.fastboot.core.operation;

import com.bckj.fastboot.core.operation.context.OperationContext;

import java.util.Objects;

public interface Operation {

    void execute(OperationContext context);

    default <T> T castCtx(OperationContext context, Class<T> clazz) {
        return clazz.cast(context);
    }

    default void rollback(OperationContext context, Throwable error) { }

    default void callback(OperationContext context) { }

    default Operation compose(Operation before) {
        Objects.requireNonNull(before);
        return (t) -> { before.execute(t); execute(t); };
    }

    default Operation andThen(Operation after) {
        Objects.requireNonNull(after);
        return (t) -> { execute(t); after.execute(t); };
    }

    static Operation of(Operation... operations) {
        if (operations.length == 0) {
            return (t) -> { };
        }
        return (t) -> {
            for (Operation operation : operations) {
                operation.execute(t);
            }
        };
    }
}
